package yxy.game.pm2.active.module;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.redisson.api.RMap;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.actrushranking;
import yxy.cherry.data.bean.task;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.active.module.actcontrol.activeControl;
import yxy.game.pm2.active.module.openservicerank.OpenServiceAllServiceModule;
import yxy.game.pm2.active.module.rushtoptarget.CBTask;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.AreaModule;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.bean.module.rank.openserviceactive.RecordTaskFirstPlayrerBean;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.task.Task;
import yxy.game.pm2.bean.timeline.Timeline;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>存储不同type活动的所有任务</>
 * <p>存储不同type活动的日期信息</>
 * <p>主要用来判断类型为type的活动是否开始和查询该活动的任务有哪些</p>
 *
 * @ClassName ActiveModule_开服冲榜
 * @Author jingtao-zheng
 * @Date 2022/7/5 18:48
 * @Version 1.0
 **/
public class ActiveModule_开服冲榜 extends PlayerModule {
    public final static int acttype1 = 1001;//武将比拼
    public final static int acttype2 = 1002;//竞技争雄
    public final static int acttype3 = 1003;//等级提升
    public final static int acttype4 = 1004;//齐心协力

    private final static int HERO_COMPETITION = 1001;//武将比拼
    private final static int ARENA_HEGEMONY = 1002;//竞技争雄
    private final static int LEVEL_UP = 1003;//等级提升
    private final static int WORK_TOGETHER = 1004;//齐心协力
    private final static int HERO_COMPETITION_GROUP = 1;
    private final static int ARENA_HEGEMONY_GROUP = 2;
    private final static int LEVEL_UP_GROUP = 3;
    private final static int WORK_TOGETHER_GROUP = 4;

    private HashMap<Integer, CBTask> idtaskcode = new HashMap<Integer, CBTask>();
    private int daycondition; //开服天数开启条件
    private int operationcycle;//活动运行时间

    private int type;//活动类型

    public void setDaycondition(int daycondition) {
        this.daycondition = daycondition;
    }

    public int getDaycondition() {
        return daycondition;
    }

    public int getOperationcycle() {
        return operationcycle;
    }

    public void setOperationcycle(int operationcycle) {
        this.operationcycle = operationcycle;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public static ActiveModule_开服冲榜 get(String playerCode, int type) {
        try {
            ActiveModule_开服冲榜 module = getv(key(playerCode, type));
            if (module == null) {
                module = MySQLCacheDAO.getV(key(playerCode,type), ActiveModule_开服冲榜.class);
                if(module != null){module.set(type);}//把数据同步到redis
            }
            //开服的时候初始化用
            if (module == null) {
                module = create(playerCode, type);
            }
            //update是为了修改活动信息后可以实时的更新
            module.update(playerCode, type, module);
            module.check(type, playerCode);
            return module;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void update(String playercode, int type, ActiveModule_开服冲榜 am) {
        //玩家所在区服
        AreaBean ab = AreaModule.area(playercode);
        //去activeControl表拿配置的活动开始时间结束时间还有
        activeControl sai = activeControl.get(ab.getAreaId(), type);
        if (!sai.running()) {
            return;
        }
        am.setTimeline(sai.getTimeline());
        //设置开服天数开启条件
        am.setDaycondition(sai.getDaycondition());
        //设置活动运行时间
        am.setOperationcycle(sai.getOperationcycle());
        am.set(type);
    }

    public void check(int type, String playercode) {
        if (running()) {
            new ActOpenHandle().updateActOpen(getPlayerCode(), type, OpenType.开启);
        } else {
            new ActOpenHandle().updateActOpen(getPlayerCode(), type, OpenType.关闭);
        }

//        for (int type : RankRushEnum.getSequence()) {
//            new ActOpenHandle().updateActOpen(getPlayerCode(), type, type == getRuntype() ? OpenType.开启 : OpenType.关闭);
//        }

        TipType tt = matchTipType(type);
        boolean isTip = true;
        if (running()) {
            for (CBTask ct : getIdtaskcode().values()) {
                String taskcode = ct.getTaskcode();
                Task taskbean = Task.get(getPlayerCode(), taskcode);
                if (taskbean == null) {
                    continue;
                }

                if (taskbean.isReward()) {
                    continue;
                }

                if (taskbean.isFinish() && !taskbean.isReward()) {
                    new TipHandle().updateTip(getPlayerCode(), tt, true);
                    isTip = false;
                    break;
                }
            }
        }
        if (isTip) {
            new TipHandle().updateTip(getPlayerCode(), tt, false);
        }

        TipType tt2 = matchAllTipType(type);
        RMap<String, OpenServiceAllServiceModule> map = null;
        try {
            map = OpenServiceAllServiceModule.get(playercode, type);
        } catch (RedisException e) {
            e.printStackTrace();
        }
        for (Map.Entry<String, OpenServiceAllServiceModule> moduleEntry : map.entrySet()) {
            int canget = moduleEntry.getValue().getCanget();
            if (canget == 1) {
                new TipHandle().updateTip(getPlayerCode(), tt2, true);
                return;
            }
        }


        new TipHandle().updateTip(getPlayerCode(), tt2, false);
    }

    public static ActiveModule_开服冲榜 create(String playercode, int type) {
        //玩家所在区服
        AreaBean ab = AreaModule.area(playercode);
        //去activeControl表拿配置的活动开始时间结束时间还有
        activeControl sai = activeControl.get(ab.getAreaId(), type);
        // TODO 这里需要处理
        if (!sai.running()) {
            return null;
        }
        ActiveModule_开服冲榜 am = new ActiveModule_开服冲榜();
        am.setPlayerCode(playercode);
        am.setType(type);
        am.setTimeline(sai.getTimeline());
        //设置开服天数开启条件
        am.setDaycondition(sai.getDaycondition());
        //设置活动运行时间
        am.setOperationcycle(sai.getOperationcycle());
        //通过活动type 去策划配置的actrushranking表匹配任务组id
        int taskGroupId = matchTaskGroup(type);
        //获取活动的任务信息
        Map<String, actrushranking> datamap = DataCenter.getAllData(actrushranking.class);
        for (actrushranking data : datamap.values()) {
            if (data.getGroup() == taskGroupId) {
                int taskid = data.getTaskid();
                task taskdata = DataCenter.getData(taskid, task.class);
                if (taskdata == null) {
                    continue;
                }

                Task taskbean = Task.create(playercode, taskdata);
                CBTask ct = new CBTask(data.getId(), taskid, taskbean.getCode());
                am.getIdtaskcode().put(ct.getId(), ct);
            }
        }
        //还要记录一下这个服的这个活动时间的情况

        am.set(type);
        return am;
    }


    //判断是否开活动
    @Override
    public boolean running() {
        //获取当前时间
        DateTime now = DateTime.now();
        /**
         *  获取活动开始时间
         */
        //获取策划配置的开始时间和结束时间
        Timeline timeline = getTimeline();
        DateTime chStartTime = timeline.getStartTime();
        DateTime chendTime = timeline.getEndTime();
        //获取开服时间
        PlayerBean playerBean = PlayerBean.get(getPlayerCode());
        ServerBean serverBean = ServerBean.get(playerBean.getServerId());
        DateTime starttime = serverBean.getStarttime();
        String s = starttime.toString("yyyy-MM-dd");
        DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd");
        starttime = DateTime.parse(s, format);
        //活动开启条件
        int daycondition = getDaycondition();
        //计算真实活动开始时间=开服时间 + 活动开启条件表示的天数
        DateTime realStartDateTime = starttime.plusDays(daycondition);
        /**
         * 获取活动结束时间
         */
        //活动运行天数
        int operationcycle = getOperationcycle();
        // 真实活动结束时间 = 真实活动开始时间 + 活动运行天数
        DateTime realEndDateTime = realStartDateTime.plusDays(operationcycle);

        //计算是否开启活动
        return chStartTime.getMillis() <= now.getMillis()
                &&
                now.getMillis() <= chendTime.getMillis()
                &&
                realStartDateTime.getMillis() <= now.getMillis()
                &&
                now.getMillis() <= realEndDateTime.getMillis()
                ;
    }

    /**
     * 获取活动的真实结束时间
     */
    public long realEndTime() {
        PlayerBean playerBean = PlayerBean.get(getPlayerCode());
        ServerBean serverBean = ServerBean.get(playerBean.getServerId());
        DateTime starttime = serverBean.getStarttime();
        String s = starttime.toString("yyyy-MM-dd");
        DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd");
        starttime = DateTime.parse(s, format);
        //活动开启条件
        int daycondition = getDaycondition();
        //计算真实活动开始时间=开服时间 + 活动开启条件表示的天数
        DateTime realStartDateTime = starttime.plusDays(daycondition);
        //活动运行天数
        int operationcycle = getOperationcycle();
        // 真实活动结束时间 = 真实活动开始时间 + 活动运行天数
        DateTime realEndDateTime = realStartDateTime.plusDays(operationcycle);
        return realEndDateTime.getMillis();
    }

    static private int matchTaskGroup(int type) {
        if (type == HERO_COMPETITION) {
            return HERO_COMPETITION_GROUP;
        } else if (type == ARENA_HEGEMONY) {
            return ARENA_HEGEMONY_GROUP;
        } else if (type == LEVEL_UP) {
            return LEVEL_UP_GROUP;
        } else if (type == WORK_TOGETHER) {
            return WORK_TOGETHER_GROUP;
        }
        return -1;
    }

    static private TipType matchTipType(int type) {
        if (type == HERO_COMPETITION) {
            return TipType.活动_开服冲榜_武将比拼任务奖励;
        } else if (type == ARENA_HEGEMONY) {
            return TipType.活动_开服冲榜_竞技争雄任务奖励;
        } else if (type == LEVEL_UP) {
            return TipType.活动_开服冲榜_等级提升任务奖励;
        } else if (type == WORK_TOGETHER) {
            return TipType.活动_开服冲榜_齐心协力任务奖励;
        } else {
            return null;
        }
    }

    static private TipType matchAllTipType(int type) {
        if (type == HERO_COMPETITION) {
            return TipType.活动_开服冲榜_全服武将比拼任务奖励;
        } else if (type == ARENA_HEGEMONY) {
            return TipType.活动_开服冲榜_全服竞技争雄任务奖励;
        } else if (type == LEVEL_UP) {
            return TipType.活动_开服冲榜_全服等级提升任务奖励;
        } else if (type == WORK_TOGETHER) {
            return TipType.活动_开服冲榜_全服齐心协力任务奖励;
        } else {
            return null;
        }
    }

    public void set(int type) {
        try {
            String key1 = key(getPlayerCode(), type);
            setv(key1, this);
            //TODO 查看是否有可领取奖励 控制红点
            check(type, getPlayerCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public HashMap<Integer, CBTask> getIdtaskcode() {
        return idtaskcode;
    }

    static private String key(String playerCode, int type) {
        return String.format("PLAYER:%s:ACTIVE:%S", playerCode, type);
    }

    public String key() {
        return String.format("PLAYER:%s:ACTIVE:%S", getPlayerCode(), getType());
    }

    /**
     * 分布式锁RLock
     */
    @Override
    public String lockKey() {
        return String.format("lock:%s", key());
    }

    /**
     * 初始化全服领奖信息
     */
    public void createAll(String playercode, int type) {
        //个人领奖信息
        try {
            RMap<String, OpenServiceAllServiceModule> map = OpenServiceAllServiceModule.get(playercode, type);
            //不为空就不初始化
            if (null == map || map.size() != 0) return;
        } catch (RedisException e) {
            e.printStackTrace();
        }


        RMap<String, RecordTaskFirstPlayrerBean> beanRMap = null;
        try {
            beanRMap = RecordTaskFirstPlayrerBean.get(RecordTaskFirstPlayrerBean.key(playercode, type));
        } catch (RedisException e) {
            e.printStackTrace();
        }
        if (null == beanRMap) return;

        for (Map.Entry<String, RecordTaskFirstPlayrerBean> beanEntry : beanRMap.entrySet()) {
            RecordTaskFirstPlayrerBean bean = beanEntry.getValue();
            //初始化信息
            OpenServiceAllServiceModule module = new OpenServiceAllServiceModule();
            module.setType(type);
            module.setTaskid(bean.getTaskid());
            module.setPlayercode(bean.getPlayercode());
            module.setFirstcompletetime(bean.getFirstcompletetime());
            module.setCanget(1);
            module.set(playercode);
        }
    }

    /**
     * 开服冲榜活动结束没领取奖励,在会在玩家再次登录游戏时会以邮件形式方法给玩家
     */
    public void provideUnclaimedRewards() {
        //活动结束时间
        long endTime = realEndTime();
        //当前时间
        long nowTime = DateTime.now().getMillis();
        //如果活动已经结束
        if (nowTime > endTime) {
            //通过活动id查询玩家未完成的活动
            //遍历冲榜的所有任务
            for (CBTask ct : getIdtaskcode().values()) {
                Task task = Task.get(getPlayerCode(), ct.getTaskcode());//通过TaskCode获取玩家单个任务的详细信息
                if (task == null) {
                    continue;
                }
                yxy.cherry.data.bean.task execl = DataCenter.getData(ct.getTaskid(), yxy.cherry.data.bean.task.class);//获取策划配置的信息
                if (execl == null) {
                    continue;
                }
                //Task reward控制是否可以领取奖励                                                                   判断是没完成不能领还是已经领过了
                int canget = task.isReward() ? DrawStatus.hadget.getStatus() : task.isFinish() ? DrawStatus.canget.getStatus() : DrawStatus.cannotget.getStatus();
                //如果为1(可领取状态),就发邮件给玩家
                if (canget == 1) {
                    //发放奖励
                    ArrayList<Currency> curs = (ArrayList<Currency>) Currency.create(execl.getRewardtype(), execl.getRewardid(),
                            execl.getRewardnum());
                    String title = GameString.开服冲榜未手动领取的奖励_title().getText();
                    String name = matchName(getType());
                    String content = GameString.开服冲榜未手动领取的奖励_msg(name).getText();
                    new MailHandle().sendMail(getPlayerCode(), MailTypeEnum.Mail, title, content, CCReason.活动_开服冲榜, curs);
                    //邮件发完,修改领取状态
                    task.setReward(true);
                    task.set();
                }
            }

        }
    }

    private static String matchName(int type){
        if(type ==  HERO_COMPETITION ){
           return  "武将比拼";
        }
        if(type ==  ARENA_HEGEMONY ){
            return  "竞技争雄";
        }
        if(type ==  LEVEL_UP ){
            return  "等级提升";
        }
        if(type ==  WORK_TOGETHER ){
            return  "齐心协力";
        }
        return "";
    }

    //存储到数据库的方法
    public static void saveToDB(String playerCode, int type) {
        try {
            String key = key(playerCode,type);
            if (touchBucket(key).isExists()) {
                ActiveModule_开服冲榜 module = getv(key(playerCode,type));
                if(module != null) MySQLCacheDAO.setV(key, module);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //从redis移走数据的操作
    public static void removeAllFromRedis(String playerCode,int type) {
        try {
            touchBucket(key(playerCode,type)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

}
